%    Copyright (C) 2001, 2002 Aladdin Enterprises.  All rights reserved.
% 
% This software is provided AS-IS with no warranty, either express or
% implied.
% 
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
% 
% For more information about licensing, please refer to
% http://www.ghostscript.com/licensing/. For information on
% commercial licensing, go to http://www.artifex.com/licensing/ or
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
% San Rafael, CA  94903, U.S.A., +1(415)492-9861.

% $Id: gs_indxd.ps 6300 2005-12-28 19:56:24Z giles $
% Indexed color space method dictionary


% verify that Indexed color spaces are supported
/.setindexedspace where
  { pop }
  { currentfile closefile }
ifelse

.currentglobal true .setglobal
.cspace_util begin

%
%   <num>  <array>   restrict_index   <int>  <array>
%
% Restrict the operand to setcolor for an Indexed color space to be an
% integer in the applicable range.
%
/restrict_index
  {
    exch round cvi
    dup 0 lt
      { pop 0 }
      {
        1 index 2 get 2 copy gt
          { exch }
        if
        pop
      } 
    ifelse
    exch
  }
bind def

%
%   <num>  <array>   get_indexed_base_color   <c1> ... <cn>  <array>
%
% Get the base color corresponding to an indexed color value.
%
/get_indexed_base_color
  {
    % just in case, set the index into the appropriate range
    //restrict_index exec

    % lookup in the string or use the lookup proc
    mark 1 index 3 get dup type /stringtype eq
      {
        2 index 1 get //.cs_get_ncomps exec dup 6 -1 roll mul exch getinterval
          { 255 div }
        forall
      }
      { 4 -1 roll exch exec }
    ifelse
    counttomark 2 add -2 roll pop
  }
bind def


colorspacedict
/Indexed
  mark
    /cs_potential_indexed_base false
    /cs_potential_pattern_base true
    /cs_potential_alternate false
    /cs_potential_icc_alternate false
    /cs_get_ncomps //ncomps_1
    /cs_get_range { 0 exch 2 get 2 array astore } bind
    /cs_get_default_color { pop 0 } bind

    /cs_get_currentgray
      { //get_indexed_base_color exec 1 get //.cs_get_currentgray exec }
    bind
    /cs_get_currentrgb
      { //get_indexed_base_color exec 1 get //.cs_get_currentrgb exec }
    bind
    /cs_get_currentcmyk
      { //get_indexed_base_color exec 1 get //.cs_get_currentcmyk exec }
    bind

    % a lot of validation is done by the cs_validate method
    /cs_validate
      {
        //check_array exec
        dup 1 get //.cs_validate exec //.cs_potential_indexed_base exec not
          //setcspace_rangecheck
        if
        dup 2 get dup type /integertype ne
          //setcspace_typecheck
          {
            dup 0 lt exch 4095 gt or
              //setcspace_rangecheck
            if
          }
        ifelse
        dup 3 get dup type /stringtype eq
          {
            length
            1 index dup 2 get 1 add exch 1 get //.cs_get_ncomps exec mul
            lt
              //setcspace_rangecheck
            if
          }
          {
            //check_array exec xcheck not
              //setcspace_typecheck
            if
          }
        ifelse
      }
    bind

    % substitute the base space if appropriate
    /cs_substitute
      {
        dup 1 get //.cs_substitute exec 2 copy eq
          { pop pop dup }
          {
            % retain only the new base space
            exch pop

            % build all new structures in local VM
            .currentglobal 3 1 roll //false .setglobal

            % construct a new array and insert the new base color space            
            1 index dup length array copy dup 1 4 -1 roll put

            % restore VM mode
            3 -1 roll .setglobal
          }
        ifelse
      }
    bind

    /cs_prepare {}

    %
    % Install the current color space. Note that the alternative color
    % space will already have been set as the current color space.
    %
    % The current Ghostscript color space implementation requires that
    % color spaces that provide a base or alternative color space set
    % that base/alternative color space to be the current color space
    % before attempting to set the original color space.
    %
    /cs_install
      {
        % save the current color space
        currentcolorspace

        % set the base color space as the current color space
        1 index 1 get //forcesetcolorspace

        % set the indexed color space; restore the earlier space on error
        mark 2 index
          { .setindexedspace }
        stopped
          { cleartomark setcolorspace stop }
          { pop pop pop }
        ifelse
      }
    bind

    /cs_prepare_color //validate_1

    %
    % Adobe implementations always execute a lookup procedure when setcolor
    % is invoked. Ghostscript samples the lookup procedure when
    % setcolorspace is invoked, and then does not access it again. In the
    % unlikely event that an application depends on the Adobe-specific
    % behavior, it is replicated in this method.
    %
    /cs_complete_setcolor
      {
        3 get dup type /stringtype eq
          { pop }
          {
            currentcolor exch exec
            currentcolorspace 1 get //clear_setcolor_operands exec
          }
        ifelse
      }
    bind

  .dicttomark
put

end     % .cspace_util
.setglobal
